home *** CD-ROM | disk | FTP | other *** search
- /*
- * col.c -- manipulate columnar files
- *
- * Columns are separated by spaces and tabs.
- *
- * Usage:
- * col [-d] "$j $k ... " [infile]
- * where j, k, etc are column numbers. Input is from stdin if no
- * file is specified. Output is to stdout (you can use redirection).
- */
-
- /*
- * Copyright (c) 1985 by David Dyer-Bennet
- * Permission for non-commercial use is hereby granted; all other
- * rights are reserved.
- *
- * Written by David Dyer-Bennet
- * Terrabit Software
- * 4242 Minnehaha Ave S
- * Minneapolis, MN 55406
- * Sysop of Fido 14/341, The Terraboard, (612) 721-8967 3/12/24 24hrs
- * (612) 721-8800 NOT 24 hrs! More like noon to midnight
- */
-
- /*
- * Revision history:
- *
- * Edit Date Who Description
- *
- * Version 1.0
- * 1 6-Jan-86 DD-B Initial creation
- */
-
- #include <stdio.h>
- #include <ctype.h>
-
-
- /* External variables */
- extern int errno;
-
- /* Global variables */
-
- int debug = 0; /* Non-zero turns on debugging stuff */
-
- #define MAXCOL 80 /* Max number of columns */
- /* (numbered 0 to MAXCOL-1) */
- int pattern [MAXCOL]; /* Columns to put out */
- int patcnt; /* # of used slots in pattern [] */
-
-
- #define MAXFIELD 80 /* Max field length */
- char cols [MAXCOL] [MAXFIELD+1];/* Put data here after parsing */
- /* (Allow for terminating NUL in field) */
-
- #define MAXLINE 256 /* Note this is < maxfield * maxcol */
- char linbuf [MAXLINE+1]; /* Buffer to read line into */
- /* (Allow for terminating '\n') */
-
- /* Function declarations */
- void usage (char *);
- void parse_pat (char *);
- void parse_line (char *);
-
- main (ac, av)
- int ac;
- char *av[];
- {
- FILE *ifil;
- int saverr; /* Useed to hold an error number */
- int i, ax = 0;
- char *ap;
-
- while (*av[++ax] == '-') { /* Process leading switches */
- ap = av[ax];
- while (*++ap) { /* Multiple switches after one '-' */
- switch (*ap) {
- case 'd':
- case 'D':
- debug++;
- break;
- default:
- usage ("Invalid switch");
- break;
- } /* end switch (*ap) */
- } /* end while (*++ap) */
- } /* end while () */
-
- if (ac < ax+1) usage ("Not enough arguments");
-
- parse_pat (av[ax]); /* Set up pattern [] */
-
- if (ac > ax+2) usage ("Too many arguments");
-
- if (ac == ax+2) { /* If there is a file argument */
- ifil = fopen (av [ax+1], "r");
- if (!ifil) {
- saverr = errno;
- fprintf (stderr, "col: Can't open %s because\n", av [2]);
- errno = saverr; /* Cheat to make perror happy */
- perror (" ");
- exit (1);
- }
- } else
- ifil = stdin;
-
- while (!feof(ifil)) {
- if (fgets (linbuf, MAXLINE, ifil)) { /* If there's a line */
- parse_line (linbuf);/* Break up into cols */
- /* Write the columns in order given by pattern */
- for (i = 0; i < patcnt; i++) {
- fputs (cols [pattern [i]], stdout);
- putc (' ', stdout);
- }
- putc ('\n', stdout);
- } /* end if (fgets ()) */
- } /* end while (!feof (ifil)) */
- fclose (ifil);
- exit (0); /* All ok */
- } /* end of main () */
-
-
- void usage (s)
- char *s;
- {
- fprintf (stderr, "col: %s\n", s);
- fprintf (stderr, "Usage:\n col [-d] \"$j $k ...\" [infile]\n");
- exit (2);
- }
-
- void parse_pat (pat)
- char *pat;
- /*
- * Parse the argument into the list of columns and place in
- * pattern [].
- */
- {
- int i;
-
- if (debug) {
- fprintf (stderr, "parse_pat (\"%s\")\n", pat);
- }
-
- patcnt = 0; /* Count of used slots in pattern [] */
- while (*pat) { /* As long as there is some pattern */
- switch (*pat) {
-
- case ' ': /* White space */
- case '\t':
- break; /* Skip over it */
-
- case '$': /* Beginning of column specifier */
- if (patcnt >= MAXCOL) {
- usage ("Too many columns");
- }
- i = 0;
- while (isdigit(*++pat)) {
- i = 10*i + *pat-'0';
- }
- pattern [patcnt++] = i-1; /* User numbers from 1 */
- /* but we number from 0 */
- pat--; /* Put back our lookahead */
- break;
-
- default: /* Anything else is illegal */
- usage ("Invalid pattern");
- break;
-
- } /* end switch () */
- pat++; /* On to next pattern char */
- } /* end while (*pat) */
- if (debug > 1) {
- fprintf (stderr, "pattern is: ");
- for (i = 0; i < patcnt; i++)
- fprintf (stderr, "%d ", pattern[i]);
- fputc ('\n', stderr);
- }
- } /* end parse_pat () */
-
- void parse_line (lp)
- char *lp;
- /*
- * Parse a line into the fields in each space-delimited column,
- * placing the results in cols [] [].
- */
- {
- int cc = 0; /* Current/next column */
- char *fp; /* Pointer to current field */
- int fcnt; /* Count of chars in field */
-
- if (debug > 1) {
- fprintf (stderr, "parse_line(\"%s\")\n", lp);
- }
-
- while (*lp != '\n') { /* As long as there's something left */
- while (*lp == ' ' || *lp == '\t')
- lp++; /* Skip over white space */
- if (*lp != '\n') { /* If not at end yet */
- if (cc >= MAXCOL)
- usage ("Too many columns in input record");
- fp = cols [cc]; /* Set up pointer to field */
- fcnt = 0; /* Init field cound */
- do { /* Pick up the field */
- *fp++ = *lp++;
- fcnt++; /* Keep count, but check later */
- } while (*lp != ' ' && *lp != '\t' && *lp != '\n');
- *fp = '\0'; /* Make a real string */
- if (fcnt >= MAXFIELD)
- usage ("Maximum field length exceeded");
- cc++; /* Here's a new column */
- } /* end if (*lp != '\n') */
- } /* end while (*lp != '\n') */
- while (++cc < MAXCOL) *(cols[cc]) = '\0'; /* Clear rest */
- if (debug > 2) {
- fprintf (stderr, "Line: ");
- for (cc=0; *cols[cc]; cc++)
- fprintf (stderr, "<%s> ", cols[cc]);
- fputc ('\n', stderr);
- }
- } /* end parse_line () */
-
- /* end of col.c */
-